#include "kernel/driver/keyboarddriver.h"
#include "libs/lib.h"
#include "kernel/log/log.h"
#include "libs/msr.h"
#include "kernel/apic/apic.h"
#include "libs/io.h"







KbFile::KbFile(/* args */)
:File()
{

}

KbFile::~KbFile()
{
}



keyboarddriver* keyboarddriver::kbm = NULL;
keyboarddriver::keyboarddriver(interruptmanager* interrupts):

interrupthandler(0x21,interrupts)
{
    kbm = this;
    buf = new uint8_t[KB_BUF_SIZE];
#ifdef APIC
    p_head = buf;
    p_tail = buf;
    count = 0;
    memset(buf,0,KB_BUF_SIZE);

    IO_APIC_RET_entry entry;

    entry.vector = 0x21;
	entry.deliver_mode = APIC_ICR_IOAPIC_Fixed ;
	entry.dest_mode = ICR_IOAPIC_DELV_PHYSICAL;
	entry.deliver_status = APIC_ICR_IOAPIC_Idle;
	entry.polarity = APIC_IOAPIC_POLARITY_HIGH;
	entry.irr = APIC_IOAPIC_IRR_RESET;
	entry.trigger = APIC_ICR_IOAPIC_Edge;
	entry.mask = APIC_ICR_IOAPIC_Masked;
	entry.reserved = 0;

	entry.destination.physical.reserved1 = 0;
	entry.destination.physical.phy_dest = 0;
	entry.destination.physical.reserved2 = 0;

    wait_KB_write();
	io_out8(PORT_KB_CMD,KBCMD_WRITE_CMD);
	wait_KB_write();
	io_out8(PORT_KB_DATA,KB_INIT_MODE);

	for(uint64_t i = 0;i<1000;i++)
		for(uint64_t j = 0;j<1000;j++)
			nop();


    install((void*)&entry);
    enable();
#endif

}

keyboarddriver::~keyboarddriver()
{
#ifdef APIC
    disable();
    uninstall();

#endif

    delete buf;
}


StackFrame* keyboarddriver::handleInterrupt(StackFrame* fs){

    char keyCode = io_in8(0x60);
    
    if(p_head == buf + KB_BUF_SIZE)
        p_head = buf;
    *p_head = keyCode;
    count++;
    p_head++;


    if(!(keyCode & 0x80))
    {
        
        
        KBDRIVERMANAGER->waitQueue.wakeUp();

    }
        


    
}








int64_t KbFile::open(IndexNode* inode,File* filp){

    filp->privateData = this;
    KBDRIVERMANAGER->p_head = KBDRIVERMANAGER->buf;
    KBDRIVERMANAGER->p_tail = KBDRIVERMANAGER->buf;
    KBDRIVERMANAGER->count = 0;
    memset(KBDRIVERMANAGER->buf,0,KB_BUF_SIZE);    

    return 1;
}

int64_t KbFile::close(Indexnode* inode,File* filp){


    filp->privateData = NULL;
    KBDRIVERMANAGER->p_head = KBDRIVERMANAGER->buf;
    KBDRIVERMANAGER->p_tail = KBDRIVERMANAGER->buf;
    KBDRIVERMANAGER->count = 0;
    memset(KBDRIVERMANAGER->buf,0,KB_BUF_SIZE);   

    return 1;


}
#define	KEY_CMD_RESET_BUFFER	0
int64_t KbFile::ioctl(Indexnode* inode,File* filp,uint64_t cmd){

    switch(cmd)
    {
        case KEY_CMD_RESET_BUFFER:
            KBDRIVERMANAGER->p_head = KBDRIVERMANAGER->buf;
            KBDRIVERMANAGER->p_tail = KBDRIVERMANAGER->buf;
            KBDRIVERMANAGER->count = 0;
            memset(KBDRIVERMANAGER->buf,0,KB_BUF_SIZE); 
        break;

        default:
        break;




    }

    return 0;

}


int64_t KbFile::read(char* buf, uint64_t count,int64_t* position){

    //  if(isSMP)
	// 	BREAK();
    int64_t counter = 0;
    uint8_t* tail = 0;
   
    if(KBDRIVERMANAGER->count == 0)
    {  
        // LOG_ERROR("Error before\n");
        KBDRIVERMANAGER->waitQueue.sleepOn();
       
    }
    
    counter = KBDRIVERMANAGER->count >= count ? count : KBDRIVERMANAGER->count;

    tail = KBDRIVERMANAGER->p_tail;
    if(counter <= (KBDRIVERMANAGER->buf + KB_BUF_SIZE - tail))
    {   
        copy_to_user(tail,buf,counter);
        
        KBDRIVERMANAGER->p_tail += counter;
  
    }
    else
    {   
        
        copy_to_user(tail,buf,(KBDRIVERMANAGER->buf + KB_BUF_SIZE - tail));
        copy_to_user( KBDRIVERMANAGER->buf,buf,counter - (KBDRIVERMANAGER->buf + KB_BUF_SIZE - tail));
        KBDRIVERMANAGER->p_tail = KBDRIVERMANAGER->buf + counter - (KBDRIVERMANAGER->buf + KB_BUF_SIZE - tail); // 这样重置P_TAIL
        // KBDRIVERMANAGER->p_tail = KBDRIVERMANAGER->p_head + counter - (KBDRIVERMANAGER->buf + KB_BUF_SIZE - tail);

    }   
   
    KBDRIVERMANAGER->count -= counter;

    return counter;

}

int64_t KbFile::write(char* buf, uint64_t count,int64_t* position){

    return 0;


}